package com.engine.salary.formlua.util;

import com.alibaba.fastjson.JSONObject;
import com.engine.salary.formlua.core.exception.ErrorType;
import com.engine.salary.formlua.entity.parameter.DataType;
import com.engine.salary.formlua.entity.parameter.FormulaContext;
import com.engine.salary.formlua.entity.parameter.FuncNames;
import com.weaver.esb.server.enums.ParamType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;


public class IgnoreParamFilter {
    protected static final Logger logger = LoggerFactory.getLogger(IgnoreParamFilter.class);
    private static JSONObject errorJson = null;
    private static String[] dateFuncs = new String[]{"YEAR", "MONTH", "DAY", "HOUR", "MINUTE", "SECOND"};
    private static String[] numberOperArray = new String[]{">", "<", ">=", "<="};

    public static void main(String[] args) throws Exception {
        DataType dataType = new DataType();
        dataType.setDataType(DataType.NUMBER);
        dataType.setContent(0.0);
//		DataType dataType2=new DataType();
//		dataType2.setDataType(DataType.STRING);
//		DataType dataType3=new DataType();
//		dataType3.setDataType(DataType.STRING);

        filterCompareFunc("", 0.5);
    }

    /**
     * 判断是人员参数
     *
     * @param object
     * @return
     */
    public static boolean isEmployee(Object object) {
//        if (object instanceof DataType) {
//            DataType dataType = (DataType) object;
//            if (dataType.getComponentKey() != null && dataType.getComponentKey().equalsIgnoreCase(ComponentType.Employee.toString())) {
//                return true;
//            }
//        }
        return false;
    }

    /**
     * 通用的校验参数类型一致的方法
     *
     * @param objects
     * @return
     */
    public static boolean checkType(Object... objects) {
        if (objects == null || objects.length == 0) {
            return true;
        }
        Map<String, Object> typeCheckMap = new HashMap<>();
        int i;
        for (i = 0; i < objects.length; i++) {
            Object obj = objects[i];
            if (obj instanceof DataType) {
                DataType dataType = (DataType) obj;
                if (StringUtils.isNotEmpty(dataType.getDataType())) {
                    typeCheckMap.put(DataType.returnType(dataType.getDataType()).toLowerCase(), obj);
                } else if (StringUtils.isNotEmpty(dataType.getComponentKey())) {
                    typeCheckMap.put(DataType.returnType(dataType.getComponentKey()).toLowerCase(), obj);
                }
            } else {
                String localtype = obj.getClass().getName();
                typeCheckMap.put(DataType.returnType(ExcelParamUtil.getParamType(localtype).toLowerCase()), obj);
            }
        }
        if (typeCheckMap.keySet().size() > 1) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 校验参数是否统一了类型
     *
     * @param objects
     * @return
     */
    public static boolean commonCheckParamsType(Object... objects) {
        if (objects == null || objects.length == 0) {
            return false;
        }
        String type = null;
        String objFunc = objects[objects.length - 1].toString();
        for (int i = 0; i < objects.length - 1; i++) {
            Object obj = objects[i];

            String loopType = ExcelParamUtil.getParamType(obj);
            if (type == null) {
                type = loopType;
            } else {
                if (!type.equalsIgnoreCase(loopType)) {
                    return false;
                }
            }
        }
        return true;
    }

    public static void filterParams(String func, int min, int max, Object... objects) {
        Integer number = getSetFuncNumber(func);
        if (null == objects) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数参数为空");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (objects.length < min) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数至少需要" + min + "个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (max > 0 && objects.length > max) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数最多允许" + max + "个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
    }

    public static void filterDateParamTypes(String func, int funcNumber, Class[] typeClasses, Object... objects) {
        Integer number = funcNumber;
        if (null == objects || null == typeClasses || objects.length == 0 || typeClasses.length == 0 || objects.length > typeClasses.length) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数参数错误");
            throw new RuntimeException(errorJson.getString("msg"));
        }
    }

    /**
     * 通用验证方法
     *
     * @param func
     * @param min
     * @param max
     * @param typeClasses
     * @param objects
     */
    public static void commonFilter(String func, int min, int max, Class[] typeClasses, Object... objects) {
        Integer number = getSetFuncNumber(func);
        if (null == objects) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数参数为空");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (objects.length < min) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数至少需要" + min + "个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (max > 0 && objects.length > max) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数最多允许" + max + "个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (typeClasses != null && typeClasses.length > 0) {
            if (null == objects || objects.length == 0 || typeClasses.length == 0 || objects.length > typeClasses.length) {
                errorJson = ErrorUtil.buildError(func, 0, number, func + "函数参数错误");
                throw new RuntimeException(errorJson.getString("msg"));
            }
            for (int i = 0; i < objects.length; i++) {
                String fieldType = null;
                String paramType = ExcelParamUtil.getParamType(typeClasses[i].getName());
                paramType = ExcelParamUtil.checkParamType(paramType);
                if (objects[i] instanceof DataType) {
                    DataType dataType = (DataType) objects[i];
                    List<String> datafunclist = Arrays.asList(dateFuncs);
                    if (datafunclist.contains(func)) {
                        fieldType = dataType.getDataType();
                    } else {
                        fieldType = ExcelParamUtil.checkParamType(dataType.getDataType());
                    }
                } else {
                    fieldType = ExcelParamUtil.getParamType(objects[i].getClass().getName());
                    fieldType = ExcelParamUtil.checkParamType(fieldType);
                }
                if (null == fieldType) {
                    errorJson = ErrorUtil.buildError(func, i + 1, number, func + "函数参数错误");
                    throw new RuntimeException(errorJson.getString("msg"));
                }
                boolean compareResult = false;
                if (paramType.equals("dateandstring") && (fieldType.toLowerCase().equals("string") || fieldType.toLowerCase().equals("date"))) {
                    compareResult = true;
                } else if (paramType.toLowerCase().equals(fieldType.toLowerCase())) {
                    compareResult = true;
                } else if (ExcelParamUtil.inNumber(paramType) && ExcelParamUtil.inNumber(fieldType)) {
                    compareResult = true;
                } else {
                    if (!compareResult) {
                        errorJson = ErrorUtil.buildError(func, (i + 1), number, func + "函数参数类型错误");
                        throw new RuntimeException(errorJson.getString("msg"));
                    }
                }
            }
        }

    }


    /**
     * 过滤字符串函数参数
     *
     * @param objects
     */
    public static void filterStringConcat(int min, int max, Object... objects) {

        Integer number = getSetFuncNumber(FuncNames.CONCAT.toString());
        String func = FuncNames.CONCAT.toString();
        if (objects.length < min) {
            errorJson = ErrorUtil.buildError(func, number, number, "CONCAT函数至少需要" + min + "个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (max > 0 && objects.length > max) {
            errorJson = ErrorUtil.buildError(func, number, number, "CONCAT函数最多允许" + min + "个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
    }


    /**
     * 过滤聚合函数参数
     *
     * @param objects
     * @throws RuntimeException
     */
    public static void filterAggFunc(String func, Object... objects) throws RuntimeException {
        Integer number = getSetFuncNumber(func);
        Map<String, String> map = new HashMap<>();
        boolean mustNumber = false;
        if (objects == null) {
            errorJson = ErrorUtil.buildError(func, number, number, func + ErrorType.VAR_TYPE_WRONG.name());
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (objects.length > 2) {
            errorJson = ErrorUtil.buildError(func, number, number, func + "函数最多只支持两个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        checkArrayParamNull(func, number, objects);
        Object obj = objects[0];
        if (func.equals("MAX") || func.equals("MIN") || func.equals("AVG") || func.equals("SUM")) {
            mustNumber = true;
        }
        if (!(obj instanceof DataType)) {
            number = getSetFuncNumber(obj.toString());
            errorJson = ErrorUtil.buildError(obj.toString(), number, number, func + "函数参数错误");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        String paramType = "";
        DataType dataType = (DataType) objects[0];
        if (dataType.getFormId() == null && dataType.getFieldId() == null) {
            number = getSetFuncNumber(obj.toString());
            errorJson = ErrorUtil.buildError(obj.toString(), number, number, func + "函数参数错误");
            throw new RuntimeException(errorJson.getString("msg"));
        }

        //除了
        if (mustNumber) {
            if (objects[0] instanceof DataType && dataType.getDataType() != null) {
                paramType = ExcelParamUtil.checkParamType(dataType.getDataType());
                if (paramType != null) {
                    paramType = ExcelParamUtil.checkParamType(paramType);
                }
            } else {
                errorJson = ErrorUtil.buildError(func, number, number, func + "函数参数错误");
                throw new RuntimeException(errorJson.getString("msg"));
            }
            if (paramType == null || !(paramType.equals(DataType.NUMBER))) {
                errorJson = ErrorUtil.buildError(func, number, number, func + "第一个变量必须为数字字段");
                throw new RuntimeException(errorJson.getString("msg"));
            }
        } else {
            if (dataType.getFormId() == null) {
                errorJson = ErrorUtil.buildError(func, number, number, func + "第一个变量必须为表格");
                throw new RuntimeException(errorJson.getString("msg"));
            }
        }

        for (int i = 0; i < objects.length; i++) {
            Object param = objects[i];
            if (param != null && param instanceof DataType) {
                DataType pramDataType = (DataType) param;
                if (pramDataType.getSubLogic() != null && pramDataType.getSubLogic().size() > 1) {
                    throw new RuntimeException(func + "函数的参数不能嵌套使用逻辑函数（AND、OR）");
                }
            }
        }

    }

    public static void filterInFunc(Object... objects) {
        String oper = objects[objects.length - 1].toString();
        Integer number = getSetFuncNumber(oper);
        List<Object> params = (List<Object>) objects[0];
        if (params.size() < 2) {
            errorJson = ErrorUtil.buildError(oper, number, number, "IN操作符第二个条件至少需要两个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        String type = null;
        for (Object object : params) {
            String thisType;
            if (object instanceof DataType) {
                thisType = ((DataType) object).getDataType();
                if (type == null) {
                    type = thisType;
                } else {
                    if (!thisType.equals(type)) {
                        errorJson = ErrorUtil.buildError(oper, number, number, "IN操作符参数类型不一致");
                        throw new RuntimeException(errorJson.getString("msg"));
                    }
                }
            }
        }
    }

    /***
     * 过滤比较操作符的参数类型
     * @param objects
     */
    public static void filterCompareFunc(Object... objects) throws Exception {
        String oper = objects[objects.length - 1].toString();
        Integer number = getSetFuncNumber(oper);
        String type1 = "";
        String type2 = "";

        for (int i = 0; i < objects.length; i++) {
            Object object = objects[i];
            if (object == null) {
                throw new RuntimeException("[" + oper + "]" + ErrorType.VAR_NOT_NULL.name());
            }
        }
        if (objects.length < 2) {
            throw new RuntimeException("[" + oper + "]" + ErrorType.VAR_NOT_NULL.name());
        }
        boolean isDate = false;
        for (int i = 0; i < objects.length - 1; i++) {

            Object object = objects[i];
            if (object == null) {
                throw new RuntimeException("[" + oper + "]" + ErrorType.VAR_NOT_NULL.name());
            }
            String typeName = "";

            if (object instanceof DataType) {
                DataType param = (DataType) object;
                typeName = param.getDataType();
                if (typeName.equalsIgnoreCase(DataType.FORM)) {
                    throw new RuntimeException("[" + oper + "]" + ErrorType.CANT_FORM_FIELD.name());
                }

                if (!typeName.toLowerCase().equals("option")) {
                    typeName = ExcelParamUtil.checkParamType(typeName.toLowerCase());
                }
                if (typeName.toLowerCase().equals(DataType.DATE.toLowerCase())) {
                    typeName = DataType.STRING;
                    isDate = true;
                }
            } else {
                //校验比较操作符中的数组是不是为空
                if (object instanceof Object[]) {
                    Object[] arrayP = (Object[]) object;
                    if (arrayP.length == 0) {
                        throw new RuntimeException("[" + oper + "]" + ErrorType.VAR_NOT_NULL.name());
                    }
                    if (arrayP[0] instanceof DataType) {
                        DataType arrayParamOne = (DataType) arrayP[0];
                        typeName = arrayParamOne.getDataType();
                    } else {
                        typeName = ExcelParamUtil.getParamType(arrayP[0].getClass().getName());
                    }
                } else {
                    typeName = ExcelParamUtil.getParamType(object.getClass().getName());

                }
                if (!typeName.equalsIgnoreCase("option")) {
                    typeName = ExcelParamUtil.checkParamType(typeName);
                }
            }
            //判断非等于和不等于操作符的两端参数是否为数字，不是数字返回错误
            if (!isDate && !oper.equals("=") && !oper.equals("!=") && (typeName.toLowerCase().equals(DataType.OPTION))) {
                errorJson = ErrorUtil.buildError(oper, 1, number, "比较操作符'" + oper + "'不支持选项类型的运算");
                throw new RuntimeException(errorJson.getString("msg"));
            }


            if (i == 0) {
                type1 = typeName;
            } else {
                type2 = typeName;
            }
        }
        List<String> operList = Arrays.asList(numberOperArray);
        if (operList.contains(oper) && (type1.equalsIgnoreCase("string") || type2.equalsIgnoreCase("string"))) {
            String msg = "[" + oper + "]操作符不允许非数字类型参数";
            throw new RuntimeException(msg);
        }
        if (!IgnoreParamFilter.checkType(objects[0], objects[1])) {
            errorJson = ErrorUtil.buildError(oper, 1, number, "比较操作符参数类型不一致");
            throw new RuntimeException(errorJson.getString("msg"));
        }

        if (objects[0] instanceof Object[]) {
            errorJson = ErrorUtil.buildError(oper, 1, number, "比较操作符不支持数组参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
    }

    /**
     * 过滤日期函数参数
     *
     * @param objects
     * @throws Exception
     */
    public static void filterDateFunc(Object... objects) throws Exception {
        Integer number = getSetFuncNumber("");
        boolean isWrong = false;
        if (objects.length < 2) {
            errorJson = ErrorUtil.buildError("Date", 0, number, "日期函数参数错误");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        int idx = 1;
        for (Object object : objects) {

            if (!(object instanceof String) && !(object instanceof Date) && !(object instanceof DataType)) {
                isWrong = true;
                break;

            } else if (object instanceof DataType) {
                Object content;
                DataType dataType = (DataType) object;
                content = dataType.getContent();
                if (!(content instanceof String) && !(content instanceof Date) && !(content instanceof DataType)) {
                    isWrong = true;
                    break;
                }
            }
            idx++;
        }
        if (isWrong) {
            errorJson = ErrorUtil.buildDataError("Date", idx, objects, "日期函数参数错误");
            throw new RuntimeException(errorJson.getString("msg"));
        }

    }


    /**
     * 逻辑函数过滤器
     *
     * @param objects
     */
    public static void filterLogicAndORFunc(Object... objects) {
        String method = objects[objects.length - 1].toString();
        FormulaContext.get().setValue(method);
        Object[] paramArray = (Object[]) objects[0];
        Integer number = getSetFuncNumber(method);
        if (null == paramArray || paramArray.length == 0) {
            errorJson = ErrorUtil.buildError(method, 0, number, method + "函数参数不能为空");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        for (int i = 0; i < paramArray.length; i++) {
            String fieldType = null;
            if (paramArray[i] instanceof DataType) {
                DataType dataType = (DataType) paramArray[i];
                fieldType = dataType.getDataType();
            } else {
                fieldType = ExcelParamUtil.getParamType(paramArray[i].getClass().getName());
            }
            fieldType = ExcelParamUtil.checkParamType(fieldType);
            if (!fieldType.equalsIgnoreCase(ParamType.BOOLEAN.getValue())) {
                errorJson = ErrorUtil.buildError(method, (i + 1), number, method + "函数第" + (i + 1) + "个条件必须为真假值");
                throw new RuntimeException(errorJson.getString("msg"));
            }
        }
    }

    /**
     * 判断IF函数的参数合法性
     *
     * @param objects
     */
    public static void filterIfFunc(Object... objects) {
        Integer number = getSetFuncNumber("IF");
        String cndType = "";
        if (objects[0] instanceof DataType) {
            DataType dataType = (DataType) objects[0];
            cndType = dataType.getDataType();
        } else {
            cndType = ExcelParamUtil.getParamType(objects[0].getClass().getName());
        }
        cndType = ExcelParamUtil.checkParamType(cndType);
        if (null == cndType || !cndType.equals(ParamType.BOOLEAN.getValue())) {
            errorJson = ErrorUtil.buildError("If", 0, number, "IF函数条件应为真假值类型");
            throw new RuntimeException(errorJson.getString("msg"));
        }

        String pType1 = "";
        String pType2 = "";
        if (objects[1] instanceof DataType) {
            DataType dataType = (DataType) objects[1];
            pType1 = dataType.getDataType();
        } else {
            pType1 = ExcelParamUtil.getParamType(objects[1].getClass().getName());
        }
        pType1 = ExcelParamUtil.checkParamType(pType1);
        if (objects[2] instanceof DataType) {
            DataType dataType = (DataType) objects[2];
            pType2 = dataType.getDataType();
        } else {
            pType2 = ExcelParamUtil.getParamType(objects[2].getClass().getName());
        }
        pType2 = ExcelParamUtil.checkParamType(pType2);
        if (!pType1.equals(pType2)) {
            errorJson = ErrorUtil.buildError("If", 0, number, "IF函数表达式返回值不一致");
            throw new RuntimeException(errorJson.getString("msg"));
        }
    }

    public static void filterLikeFunc(Object... objects) {
        Integer number = getSetFuncNumber("LIKE");
        String sourceTxt = "";
        List<Object> params = new ArrayList<Object>() {
        };
        if (objects.length < 2) {
            errorJson = ErrorUtil.buildError("LIKE", 0, number, "LIKE函数至少需要两个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        } else if (objects.length > 2) {
            errorJson = ErrorUtil.buildError("LIKE", 0, number, "LIKE函数最多支持两个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        for (Object obj : objects) {
            if (obj.getClass().isArray()) {
                Object[] subArray = (Object[]) obj;
                for (int i = 0; i < subArray.length; i++) {
                    params.add(subArray[i]);
                }
            } else {
                params.add(obj);
            }
        }
        Object object = params.get(0);
        if (object instanceof DataType) {
            DataType dataType = (DataType) object;
            sourceTxt = dataType.getDataType();
        } else {
            sourceTxt = ExcelParamUtil.getParamType(object.getClass().getName());
        }
        sourceTxt = ExcelParamUtil.checkParamType(sourceTxt);
        if (null == sourceTxt || !sourceTxt.toLowerCase().equals(ParamType.STRING.getValue().toLowerCase())) {
            String key = ExcelParamUtil.getKeyString(object);
            number = getSetFuncNumber(key);
            errorJson = ErrorUtil.buildError(key, 0, number, "LIKE函数第1个参数应该为文本类型");
            throw new RuntimeException(errorJson.getString("msg"));
        }

        for (int i = 0; i < params.size(); i++) {
            Object txtObj = params.get(i);
            if (null == txtObj) {
                errorJson = ErrorUtil.buildError("LIKE", (i + 1), number, "LIKE函数条件错误");
                throw new RuntimeException(errorJson.getString("msg"));
            }
            String txt = "";
            if (txtObj instanceof DataType) {
                DataType dataType = (DataType) txtObj;
                txt = dataType.getDataType();
            } else {
                txt = ExcelParamUtil.getParamType(txtObj.getClass().getName());
            }
            txt = ExcelParamUtil.checkParamType(txt);
            if (!txt.toLowerCase().equals(ExcelParamUtil.getParamType(ParamType.STRING.getValue().toLowerCase()))) {
                errorJson = ErrorUtil.buildError("LIKE", (i + 1), number, "LIKE函数条件数组第" + (i + 1) + "个参数应该为文本类型");
                throw new RuntimeException(errorJson.getString("msg"));
            }
        }

    }


    public static int getSetFuncNumber(String func) {
        Integer number = 0;
        FormulaContext.get().getValue(func);
        if (number == null || number == 0) {
            FormulaContext.get().setValue(func);
            number = FormulaContext.get().getValue(func);
        } else {
            FormulaContext.get().setValue(func);
            number = FormulaContext.get().getValue(func);
        }
        return number;
    }

    public static void checkArrayParamNull(String func, int number, Object[] objects) {
        for (Object object : objects) {
            if (object == null) {
                errorJson = ErrorUtil.buildError(func, 0, number, func + "函数条件存在未知参数");
                throw new RuntimeException(errorJson.getString("msg"));
            }
        }
    }

    /**
     * 校验数学加减乘除运算符号
     *
     * @param objects
     * @param oper
     */
    public static void checkNumberOper(Object[] objects, String oper) {
        Integer number = getSetFuncNumber("");
        if (objects.length != 2) {
            errorJson = ErrorUtil.buildError(oper, 1, number, "操作符只支持数字类型的运算");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        String type1 = "";
        String type2 = "";
        for (int i = 0; i < objects.length; i++) {

            Object object = objects[i];
            if (object == null) {
                errorJson = ErrorUtil.buildError(oper, 1, number, "[" + oper + "]" + "操作符参数不能为空");
                throw new RuntimeException(errorJson.getString("msg"));
            }
            String typeName = "";

            if (object instanceof DataType) {
                DataType param = (DataType) object;
                if (param.getContent() == null) {
                    param.setContent(0);//没有值时给0，保存函数运算结果
                }
                if (param.getName() != null && param.getName().equals("当前表格")) {
                    errorJson = ErrorUtil.buildError(oper, 1, number, "[" + oper + "]" + "操作符参数不能为空");
                    throw new RuntimeException(errorJson.getString("msg"));
                }
                typeName = param.getDataType();
                if (!typeName.toLowerCase().equals("option")) {
                    typeName = ExcelParamUtil.checkParamType(typeName.toLowerCase());
                }
                if (typeName.toLowerCase().equals(DataType.DATE.toLowerCase())) {
                    typeName = DataType.STRING;
                }
            } else if (object instanceof Date) {
                typeName = "string";
                //当参数为数组时
            } else if (object instanceof Object[]) {
                Object[] objArray = (Object[]) object;
                String arrayType = null;
                for (Object obj : objArray) {
                    String localType = null;
                    if (obj instanceof DataType) {
                        localType = ExcelParamUtil.getParamType(obj);
                        localType = ExcelParamUtil.checkParamType(localType);
                    } else {
                        localType = ExcelParamUtil.getParamType(obj.getClass().getName()).toLowerCase();
                        localType = ExcelParamUtil.checkParamType(localType);
                    }
                    if (arrayType == null) {
                        arrayType = localType;
                    } else {
                        if (!arrayType.equals(localType)) {
                            errorJson = ErrorUtil.buildError(oper, 1, number, "操作符参数类型不一致");
                            throw new RuntimeException(errorJson.getString("msg"));
                        }
                    }
                }
                typeName = arrayType;
            } else {
                typeName = ExcelParamUtil.getParamType(object.getClass().getName());
                typeName = ExcelParamUtil.checkParamType(typeName);
            }
            //判断非等于和不等于操作符的两端参数是否为数字，不是数字返回错误
            if (!typeName.toLowerCase().equals(DataType.NUMBER)) {
                errorJson = ErrorUtil.buildError(oper, 1, number, "操作符只支持数字类型的运算");
                throw new RuntimeException(errorJson.getString("msg"));
            }

            if (i == 0) {
                type1 = typeName;
            } else {
                type2 = typeName;
            }
        }
        if (!type1.toLowerCase().equals(type2.toLowerCase()) || type1.equals("") || type2.equals("")) {
            errorJson = ErrorUtil.buildError(oper, 1, number, "操作符参数类型不一致");
            throw new RuntimeException(errorJson.getString("msg"));
        }

    }

    /**
     * 校验分数取值函数
     *
     * @param func
     * @param objects
     */
    public static void checkFraction(String func, Object... objects) {
        Integer number = getSetFuncNumber(func);
        if (objects == null || objects.length == 0) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数参数为空");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (objects.length > 1) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数参数错误");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        Object object = objects[0];
        if (object instanceof DataType) {
            DataType dataType = (DataType) object;
            if (null == dataType.getScore()) {
                errorJson = ErrorUtil.buildError(func, 0, number, func + "函数参数类型错误");
                throw new RuntimeException(errorJson.getString("msg"));
            }
        }

    }

    public static void checkValiIdCard(String func, Object... objects) {
        Integer number = getSetFuncNumber(func);
        if (objects == null || objects.length == 0) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数参数为空");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (objects.length != 2) {
            errorJson = ErrorUtil.buildError(func, 0, number, func + "函数只允许两个参数");
            throw new RuntimeException(errorJson.getString("msg"));
        }
        if (objects[0] instanceof DataType) {
            DataType dataType = (DataType) objects[0];
            if (dataType.getDataType().equalsIgnoreCase(DataType.OPTION) || dataType.getDataType().equalsIgnoreCase(DataType.DATE)) {
                errorJson = ErrorUtil.buildError(func, 0, number, func + "函数只允许操作数字或字符");
                throw new RuntimeException(errorJson.getString("msg"));
            }
        }
    }

    /**
     * 校验参数类型
     *
     * @param paramArray
     * @param exclDataTypeList
     * @return
     */
    public static List checkParamType(Object[] paramArray, List<String> exclDataTypeList) {
        List<Integer> errorIdxList = new ArrayList();
        if (paramArray != null && paramArray.length != 0) {
            for (int i = 0; i < paramArray.length; i++) {
                Object object = paramArray[i];
                if (object instanceof DataType) {
                    DataType paramDataType = (DataType) object;
                    if (paramDataType.getDataType() != null && !paramDataType.getDataType().equalsIgnoreCase(exclDataTypeList.get(i))) {
                        errorIdxList.add(i);
                        return errorIdxList;
                    }
                } else {
                    String typeString = ExcelParamUtil.getParamType(object.getClass().getName());
                    typeString = DataType.returnType(typeString);
                    if (!typeString.equalsIgnoreCase(exclDataTypeList.get(0))) {
                        errorIdxList.add(i);
                        return errorIdxList;
                    }
                }
            }
        }
        return errorIdxList;
    }


}
